import React from 'react'

import { Toast } from 'antd-mobile'

import axios from 'axios'

import API from '@/utils/api'

import NavHeader from '../../components/NavHeader'

// import './index.scss'

import styles from './index.module.css' 

//导入utils中获取当前城市定位的方法
import {getCurrentCity} from '../../utils'

//导入react-virtualized的List组件
import { List, AutoSizer } from 'react-virtualized'

//列表数据的数据源
// const list = Array(100).fill('react-virtualized')


//数据格式化方法
const formatCityData=(list) => {
    const cityList={}
    // const cityIndex=[]
    //1.遍历list数组
    list.forEach(item=>{
        //2.获取每一个城市的首字母
        const first=item.short.substr(0,1)
        //3.判断cityList中是否有该分类
        if(!cityList[first]){
            //4.如果没有就先创建一个数组然后把当前城市信息添加到数组中
            cityList[first]=[item]
        }else{
            //5.如果有直接往该分类里push数据
            cityList[first].push(item)
        }
    })
    const cityIndex=Object.keys(cityList).sort()
    return {
        cityList,
        cityIndex
    }
}

//索引(A、B等)的高度
const TITLE_HEIGHT = 36
//每个城市名称的高度
const NAME_HEIGHT = 50

//处理字母索引的方法
const formatCityIndex=(letter)=>{
    switch(letter){
        case '#':
            return '当前定位'
        case 'hot':
            return '热门城市'
        default:
            return letter.toUpperCase()
    }
}

//有房源的城市
const HOUSE_CITY=['北京','上海','广州','深圳']

export default class CityList extends React.Component{
    constructor(props){
        super(props)
        //将获取到的cityList和cityIndex添加为组建的状态数据
        this.state={
            cityList: null,
            cityIndex: [],
            //指定右侧字母索引列表高亮的索引号
            activeIndex: 0
        }
        //创建Ref对象
        this.cityListComponent=React.createRef()
    }
    async componentDidMount(){
        await this.getCityList()
        //调用measureAllRows,提前计算List中每一行的高度实现scrollTo方法的精确跳转
        //调用这个方法的时候需要保证List组件有数据了获取数据的方法是异步的,如果List组件数据为空就会导致该方法报错
        //只要保证这个方法是在获取数据之后调用的即可
        this.cityListComponent.current.measureAllRows()
    }
    //封装获取城市列表数据的方法
    async getCityList(){
        const {data: res} = await API.get(`/area/city`,{params:{level: 1}})
        const { cityList, cityIndex } = formatCityData(res.body)
        //获取热门城市列表数据
        const {data: hotRes} = await API.get('/area/hot')
        cityList['hot'] = hotRes.body
        cityIndex.unshift('hot')
        //获取当前定位城市
        const curCity = await getCurrentCity()
        cityList['#'] = [curCity]
        cityIndex.unshift('#')
        this.setState({
            cityList,
            cityIndex
        })
    }
    //渲染每一行数据的渲染函数
    //函数的返回值就表示最终渲染在页面的内容
    rowRenderer=({
        key,
        index,//索引号
        isScrolling,//当前项是否在滚动中
        isVisible,//当前项在LIst中视可见的
        style //指定每一行的位置
    })=>{
        //获取每一行的字母索引
        const {cityIndex, cityList} = this.state
        const letter=cityIndex[index]
        //获取指定索引下的列表城市数据
        return (
            <div key={key} style={style} className={styles.city}>
                <div className={styles.title}>{formatCityIndex(letter)}</div>
                {
                    cityList[letter].map(item=>
                    <div 
                    className={styles.name}
                    key={item.value}
                    onClick={()=>{this.changeCity(item)}}>
                        {item.label}
                    </div>)
                }
            </div>
        )
    }
    //创建动态计算每一行高度的方法
    getRowHeight=({index})=>{
        //索引标题的高度+城市数量*城市名称的高度
        //TITLE_HEIGHT+cityList[cityIndex[index]].length*NAME_HEIGHT
        const {cityList,cityIndex}=this.state
        return TITLE_HEIGHT+cityList[cityIndex[index]].length*NAME_HEIGHT
    }
    //封装渲染右侧列表索引的方法
    renderCityIndex(){
        //获取到索引数组 cityIndex，遍历cityIndex，渲染索引列表
        const {cityIndex,activeIndex} = this.state
        return cityIndex.map((item,index)=>(
            <li className={styles.cityIndexItem} key={index} onClick={()=>{
                this.setState({
                    activeIndex: index
                })
                this.cityListComponent.current.scrollToRow(index)
            }}>
                <span className={activeIndex===index?`${styles.indexActive}`:''}>{item==='hot'?'热':item.toUpperCase()}</span>
            </li>
        ))
    }
    // 给list组件添加onRowsRendered配置项，用于获取当前列表渲染的行信息，在里面就会有相应信息
    // 通过参数 startIndex 获取到 起始行对应的索引号
    // 判断 startIndex 和 activeIndex 不同时候，更新状态 activeIndex为 startIndex
    //用于获取list组件渲染行中的信息   
    onRowsRendered=({ startIndex })=>{
        const {activeIndex}=this.state
        if(activeIndex!==startIndex){
            this.setState(
                {activeIndex: startIndex}
            )
        }
    }
    changeCity(curcity){
        const {label,value}=curcity
        if(HOUSE_CITY.indexOf(label)>-1){
            localStorage.setItem('hkzf_city',JSON.stringify({label,value}))
            this.props.history.go(-1)
        }else{
            Toast.info('该城市暂无房源', 1, null, false)
        }
    }
    render(){
        return ( 
            <div className={styles.citylist}>
                {/* 顶部导航栏 */}
                {/* <NavBar
                className="navbar"
                mode="light"
                icon={<i className="iconfont icon-back"/>}
                onLeftClick={() => this.props.history.go(-1)}
                >城市选择
                </NavBar> */}
                <NavHeader>
                    城市选择
                </NavHeader>
                {/* 城市列表 */}
                <AutoSizer>
                    {
                        ({width,height})=>{
                            return (
                                <List 
                                    ref={this.cityListComponent}
                                    width={width}
                                    height={height}
                                    //修改List组件的rowCount为cityIndex数组的长度
                                    rowCount={this.state.cityIndex.length}
                                    rowHeight={this.getRowHeight}
                                    rowRenderer={this.rowRenderer}
                                    onRowsRendered={this.onRowsRendered}
                                    scrollToAlignment="start"
                                />
                            )
                        }
                    }
                </AutoSizer>
                {/* 右侧索引列表 */}
                {/* 封装renderCityIndex方法，用来渲染城市索引列表
                在方法中，获取到索引数组 cityIndex，遍历cityIndex，渲染索引列表
                将索引hot替换成 热
                在state中添加状态 activeIndex，用来指定当前高亮的索引
                在遍历cityIndex时，添加当前字母索引是否是高亮 */}
                <ul className={styles.cityIndex}>
                    {this.renderCityIndex()}
                </ul>
            </div>
        )
    }
}

